package Reference;

import com.mongodb.MongoClient;
import com.mongodb.client.*;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.io.FileUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.net.ssl.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.concurrent.TimeUnit;

public class DownloadPDF {

    static MongoClient mongoClient = new MongoClient("192.168.1.173", 27017);
    static MongoDatabase mDatabase = mongoClient.getDatabase("巨潮网络");
    static MongoCollection collection = mDatabase.getCollection("沪市_会计差错");
    static String FILE_NAME = "";
    static Logger logger = LoggerFactory.getLogger(DownloadPDF.class);

    public static void main(String[] args) throws InterruptedException, IOException, InvalidFormatException {

        FILE_NAME = "沪市_会计差错";
        List<String[]> list = readData();
        List<String[]> downloadList = NotInLocal(list);
        for (String[] strings : downloadList){
            Download(strings);
        }
    }

    static void Download(String[] strings) throws InterruptedException {
        logger.info("----------开始下载---"+strings[0]);
        Request request = new Request.Builder()
                .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36")
                .addHeader("Referer", "http://www.cninfo.com.cn/new/fulltextSearch?notautosubmit=&keyWord=%E7%8B%AC%E8%91%A3%E6%84%8F%E8%A7%81")
                .addHeader("Host", "www.cninfo.com.cn")
                .addHeader("Connection", "keep-alive")
                .addHeader("X-Requested-With", "XMLHttpRequest")
                .url(strings[1])
                .build();

        OkHttpClient client = new OkHttpClient()
                .newBuilder().connectTimeout(60, TimeUnit.SECONDS)
                .sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())
                .hostnameVerifier(new TrustAllHostnameVerifier())
                .readTimeout(60, TimeUnit.SECONDS).build();
        client.dispatcher().setMaxRequests(10);
        client.dispatcher().setMaxRequestsPerHost(5);

        Call call=client.newCall(request);
        Response response = null;
        try{
            response = call.execute();
            while (true){
                if(response!=null&&response.isSuccessful()) {
                    byte[] data = response.body().bytes();
                    FileUtils.writeByteArrayToFile(new File("D:\\测试临时文件\\"+ FILE_NAME +"\\"+ strings[0] + ".pdf"), data);
                    logger.info("----------已下载---"+strings[0]);
                }
                break;
            }
        }catch (Exception e){
            Thread.sleep(2*1000);
            e.printStackTrace();

        }

        Thread.sleep(3000);
    }





    public static List<String[]> readData() throws IOException, InvalidFormatException {
        Workbook workbook = WorkbookFactory.create(new FileInputStream("D:\\测试临时文件\\nianhao_2020.xlsx"));
        Sheet sheet = workbook.getSheetAt(0);
        int n = sheet.getLastRowNum();
        List<String> id_list = new ArrayList<>();
        for (int i = 1; i <= n; i++){
            id_list.add(sheet.getRow(i).getCell(0)+"");
        }



        FindIterable<Document> documents = collection.find();
        Map<String, Document> documentMap = new HashMap<>();
        for (Document document : documents){
            documentMap.put(document.getString("_id"), document);
        }

        List<String[]> list = new ArrayList<>();
        for(String id : id_list){
            Document doc = documentMap.get(id);
            String titleName = documentMap.get(id).getString("title_name").replace("*", "").replace(":", "：").replace("\"", "").replace("</em>","").replace("<em>","").replace("<","（").replace(">","）");;;
            String url = "http://www.cninfo.com.cn/new/announcement/download?bulletinId=" + doc.getString("_id") + "&announceTime=" + doc.getString("announceTime");
            list.add(new String[]{titleName, url});
        }

        return list;
    }

    public static List<String[]> NotInLocal(List<String[]> excel_list){
        List<String> localFilePathList = GetAllFilePath("D:\\测试临时文件\\沪市_会计差错");

        int n = localFilePathList.size();
        for (int i = 0; i < n; i++) {
            int index = localFilePathList.get(i).indexOf("会计差错");
            int end = localFilePathList.get(i).indexOf(".pdf");
            localFilePathList.set(i, localFilePathList.get(i).substring(index+5, end));
        }

        Map<String, String[]> map = new HashMap<>();
        for (String[] strings : excel_list){
            map.put(strings[0], strings);
        }

        List<String[]> list = new ArrayList<>();
        for (String title : localFilePathList){
            if (map.containsKey(title))
                map.remove(title);
        }

        for (Map.Entry<String, String[]> item_map : map.entrySet()){
            System.out.println(item_map.getKey() + " 还未下载！");
            list.add(item_map.getValue());
        }
        return list;
    }

    public static List<String> GetAllFilePath(String base_file_path){
        /**
         * 获取base_file_path 下所有文件的绝对地址
         */
        File BaseFile = new File(base_file_path);

        if (BaseFile.isFile() || !BaseFile.exists()){
            throw new NullPointerException( base_file_path + " 该地址不是文件夹 或 该文件夹不存在， 请检查文件路径！");
        }

        File[] files = BaseFile.listFiles();
        List<String> list = new ArrayList<>();
        for (File file : files){
            if (file.isDirectory())
                list.addAll(GetAllFilePath(file.getAbsolutePath()));
            else
                list.add(file.getAbsolutePath());
        }

        return list;
    }

     private static class TrustAllCerts implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

        @Override
        public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}
    }

    private static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    private static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[] { new TrustAllCerts() }, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
        }

        return ssfFactory;
    }
}
